<?php

namespace app\store\controller;

use app\store\service\Auth;
use app\store\service\Menus;
use app\store\model\Setting;
use app\common\exception\BaseException;
use think\Db; 
use think\Request;
use think\Session;

/**
 * 商户后台控制器基类
 * Class BaseController
 * @package app\store\controller
 */
class Controller extends \think\Controller
{
    /** @var array $store 商家登录信息 */
    protected $store;

    /** @var string $route 当前控制器名称 */
    protected $controller = '';

    /** @var string $route 当前方法名称 */
    protected $action = '';

    /** @var string $route 当前路由uri */
    protected $routeUri = '';

    /** @var string $route 当前路由：分组名称 */
    protected $group = '';

    /** @var array $allowAllAction 登录验证白名单 */
    protected $allowAllAction = [
        // 登录页面
        'passport/login',
    ];

    /* @var array $notLayoutAction 无需全局layout */
    protected $notLayoutAction = [
        // 登录页面
        'passport/login',
    ];

    /**
     * 后台初始化
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function _initialize()
    {
        // 商家登录信息
        $this->store = Session::get('yoshop_store');
        // 当前路由信息
        $this->getRouteinfo();
        // 验证登录状态
        $this->checkLogin();
        // 验证当前页面权限
        $this->checkPrivilege();
        // 全局layout
        $this->layout();
        // 记录操作日志
        $this->logAdminAction();
    }


    public function logAdminAction()
    {
        // 获取管理员信息
        $adminUser = Session::get('yoshop_store');
        if (empty($adminUser)) {
            return; // 未登录管理员不记录
        }
    
        // **获取请求信息**
        $request    = request();
        $url        = $request->url();
        $method     = $request->method();
        $params     = $request->param();
        $ipAddress  = $request->ip();
        $userAgent  = $request->header('user-agent');
    
        // **获取当前菜单信息**
        $menus = $this->menus();
        $routeUri = $this->routeUri; // 当前操作的 URI (如 `store.user/add`)
    
        // **获取 `module_name` 和 `operation_desc`**
        $menuData = $this->getMenuPath($menus, $routeUri);
        $moduleName = $menuData['module'];
        $operationDesc = $menuData['desc'];
    
        // **自动补充操作名称**
        $operationType = $this->getOperationType($method, $routeUri);
        $operationDesc .= " - {$operationType}";
    
        // **保存到日志**
        Db::name('admin_log')->insert([
            'admin_user_id'  => $adminUser['user']['store_user_id'],
            'user_name'      => $adminUser['user']['user_name'],
            'operation_type' => strtoupper($method),
            'module_name'    => $moduleName,
            'method_name'    => $routeUri,
            'operation_desc' => $operationDesc,
            'request_url'    => $url,
            'request_method' => $method,
            'request_data'   => json_encode($params, JSON_UNESCAPED_UNICODE),
            'ip_address'     => $ipAddress,
            'user_agent'     => $userAgent,
            'wxapp_id'       => $adminUser['wxapp']['wxapp_id'],
            'create_time'    => time(),
        ]);
    }
    
    /**
     * 递归查找 `menu` 并拼接路径
     * @param array $menus  // 菜单数据
     * @param string $routeUri  // 当前路由
     * @param string $parentPath  // 递归拼接路径
     * @return array
     */
    /**
     * 递归查找 `menu` 并拼接完整路径
     * @param array $menus  // 菜单数据
     * @param string $routeUri  // 当前路由
     * @param string $parentPath  // 递归拼接路径
     * @return array
     */
    private function getMenuPath(array $menus, string $routeUri, string $parentPath = '')
    {
        foreach ($menus as $menu) {
            $currentPath = trim("{$parentPath}{$menu['name']}", ' - '); // 拼接路径

            // **匹配 `index`**
            if (isset($menu['index']) && $menu['index'] === $routeUri) {
                return ['module' => $menu['name'], 'desc' => $currentPath];
            }

            // **匹配 `uris`**
            if (isset($menu['uris']) && in_array($routeUri, $menu['uris'])) {
                return ['module' => $menu['name'], 'desc' => $currentPath];
            }

            // **递归查找 `submenu`**
            if (isset($menu['submenu'])) {
                $result = $this->getMenuPath($menu['submenu'], $routeUri, "{$currentPath} - ");
                if ($result['desc'] !== '未知操作') {
                    return $result;
                }
            }
        }

        // **未找到匹配项**
        return ['module' => '未知模块', 'desc' => '未知操作'];
    }
    /**
     * 获取操作名称（根据 `method` 自动识别）
     */
    private function getOperationType(string $method, string $routeUri)
    {
        // 常见操作映射
        $operationMap = [
            'add' => '添加',
            'edit' => '编辑',
            'update' => '更新',
            'delete' => '删除',
            'remove' => '移除',
            'disable' => '禁用',
            'enable' => '启用',
            'set' => '设置',
        ];

        // 解析 URL 路径的最后一部分
        $parts = explode('/', $routeUri);
        $lastSegment = end($parts);

        // **匹配操作**
        foreach ($operationMap as $keyword => $operation) {
            if (strpos($lastSegment, $keyword) !== false) {
                return $operation;
            }
        }

        // **默认操作名称**
        switch (strtoupper($method)) {
            case 'POST': return '添加';
            case 'PUT': return '更新';
            case 'DELETE': return '删除';
            default: return '操作';
        }
    }
    /**
     * 验证当前页面权限
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function checkPrivilege()
    {
        if ($this->routeUri === 'index/index') {
            return true;
        }
        // dump($this->routeUri);die;
        $excludedRoutes = ['goods/getpaibandata', 'order/receipt'];
        if (!in_array($this->routeUri, $excludedRoutes)) {
            if (!Auth::getInstance()->checkPrivilege($this->routeUri)) {
                throw new BaseException(['msg' => '很抱歉，没有访问权限']);
            }
        }
        return true;
    }

    /**
     * 全局layout模板输出
     * @throws \think\exception\DbException
     * @throws \Exception
     */
    private function layout()
    {
        // 验证当前请求是否在白名单
        if (!in_array($this->routeUri, $this->notLayoutAction)) {
            // 输出到view
            $this->assign([
                'base_url' => base_url(),                      // 当前域名
                'store_url' => url('/store'),              // 后台模块url
                'group' => $this->group,                       // 当前控制器分组
                'menus' => $this->menus(),                     // 后台菜单
                'store' => $this->store,                       // 商家登录信息
                'setting' => Setting::getAll() ?: null,        // 当前商城设置
                'request' => Request::instance(),              // Request对象
                'version' => get_version(),                    // 系统版本号
            ]);
        }
    }

    /**
     * 解析当前路由参数 （分组名称、控制器名称、方法名）
     */
    protected function getRouteinfo()
    {
        // 控制器名称
        $this->controller = toUnderScore($this->request->controller());
        // 方法名称
        $this->action = $this->request->action();
        // 控制器分组 (用于定义所属模块)
        $groupstr = strstr($this->controller, '.', true);
        $this->group = $groupstr !== false ? $groupstr : $this->controller;
        // 当前uri
        $this->routeUri = $this->controller . '/' . $this->action;
    }

    /**
     * 后台菜单配置
     * @return mixed
     * @throws \think\exception\DbException
     */
    protected function menus()
    {
        static $menus = [];
        if (empty($menus)) {
            $menus = Menus::getInstance()->getMenus($this->routeUri, $this->group);
        }
        return $menus;
    }

    /**
     * 验证登录状态
     * @return bool
     */
    private function checkLogin()
    {
        // 验证当前请求是否在白名单
        if (in_array($this->routeUri, $this->allowAllAction)) {
            return true;
        }
        // 验证登录状态
        if (empty($this->store)
            || (int)$this->store['is_login'] !== 1
            || !isset($this->store['wxapp'])
            || empty($this->store['wxapp'])
        ) {
            $this->redirect('passport/login');
            return false;
        }
        return true;
    }

    /**
     * 获取当前wxapp_id
     */
    protected function getWxappId()
    {
        return $this->store['wxapp']['wxapp_id'];
    }

    /**
     * 返回封装后的 API 数据到客户端
     * @param int $code
     * @param string $msg
     * @param string $url
     * @param array $data
     * @return array
     */
    protected function renderJson($code = 1, $msg = '', $url = '', $data = [])
    {
        return compact('code', 'msg', 'url', 'data');
    }

    /**
     * 返回操作成功json
     * @param string $msg
     * @param string $url
     * @param array $data
     * @return array
     */
    protected function renderSuccess($msg = 'success', $url = '', $data = [])
    {
        return $this->renderJson(1, $msg, $url, $data);
    }

    /**
     * 返回操作失败json
     * @param string $msg
     * @param string $url
     * @param array $data
     * @return array|bool
     */
    protected function renderError($msg = 'error', $url = '', $data = [])
    {
        if ($this->request->isAjax()) {
            return $this->renderJson(0, $msg, $url, $data);
        }
        $this->error($msg);
        return false;
    }

    /**
     * 获取post数据 (数组)
     * @param $key
     * @return mixed
     */
    protected function postData($key = null)
    {
        return $this->request->post(is_null($key) ? '' : $key . '/a');
    }

    /**
     * 获取post数据 (数组)
     * @param $key
     * @return mixed
     */
    protected function getData($key = null)
    {
        return $this->request->get(is_null($key) ? '' : $key);
    }

}
